import wx
from Constant import *
'''
GameObj_Burst :
    
        The game object of bursting. Giving burst type, bursting object and position, it will generate
    
    a bursting animation on map. When finishing bursting, system will check table - LIST_BURST_PRODUCT
    
    to judge whether it should generate some product in bursting area in map.
    
        By checking the table - LIST_IS_OBSTACLE, system can judge whether the cube can burst.
'''
class GameObj_Burst():
    '''
    Constructor : GameObj_Burst
        mainMap - object pointer - MainMap
        burstType - type of bursting
        burstObj - object of bursting
        posCenter - center position of bursting
    '''
    def __init__(self, mainMap, burstType, burstObj, posCenter):
        self._001_initialInstanceVariable(mainMap, burstType, burstObj, posCenter)
        self._003_bindAction()
        self._002_setBurstArea()
        self.SLOT001_lastingBurstEffect(None)
        self.timer_lastBurstEffect.Start(1000)
        #add score
        wx.PostEvent(self.mainMap, NewEvt_addScore(AddScore = SCORE_BURST))
        #play sound
        self.mainMap.ACT017_playSoundEffext(SOUND_BURST)
    '''
    function _001 : initialize the variables used for this object
        mainMap - object pointer - MainMap
        burstType - type of bursting
        burstObj - object of bursting
        posCenter - center position of bursting
    '''
    def _001_initialInstanceVariable(self, mainMap, burstType, burstObj, posCenter):
        #object pointer - MainMap
        self.mainMap = mainMap
        #burst type
        self.burstType = burstType
        #the object caused bursting
        self.burstObj = burstObj
        #the current index of burst image
        self.curBurstImageIndex = 0
        #center position of bursting
        self.posCenter = posCenter
        #list of bursting area
        self.list_burstArea = None
        #timer of lasting effect of fire bursting
        self.timer_lastBurstEffect = wx.Timer()
    '''
    function _002 : according to type of bursting, setting bursting area
    '''
    def _002_setBurstArea(self):
        #set bursting area
        if self.burstType == BURST_TYPE_3X3 :
            listPos = [[self.posCenter[0] - 1, self.posCenter[1] - 1],
                       [self.posCenter[0] - 1, self.posCenter[1]],
                       [self.posCenter[0] - 1, self.posCenter[1] + 1],
                       [self.posCenter[0], self.posCenter[1] - 1],
                       [self.posCenter[0], self.posCenter[1]],
                       [self.posCenter[0], self.posCenter[1] + 1],
                       [self.posCenter[0] + 1, self.posCenter[1] - 1],
                       [self.posCenter[0] + 1, self.posCenter[1]],
                       [self.posCenter[0] + 1, self.posCenter[1] + 1]]
        #killing illegal area
        index = 0
        while index < listPos.__len__() :
            isPosOutRange = self.mainMap.ACT004_judgePosIsOutOfRange(listPos[index])
            objType = self.mainMap.GET001_objTypeIn_listCube(listPos[index])
            if not isPosOutRange : #the position is legal
                isObstle = LIST_IS_OBSTACLE[str(GAME_OBJ_BURST_FIRE)][objType]
                if not isObstle :  #the cube can burst, posting destroy event to object is burst
                    if objType == GAME_OBJ_MASTER :  #the master is died
                        wx.PostEvent(self.mainMap, NewEvt_gameEnd(EndType = END_GAME_MASTER_DIE))
                    else :
                        wx.PostEvent(self.mainMap.evtCollector, NewEvt_DestroyGameObj(delPos = listPos[index], delObjType = objType, isClearAll = False))
            if isPosOutRange or isObstle :  #delete illegal bursting area
                listPos.__delitem__(index)
            else :
                index = index + 1
        #set list of bursting area
        self.list_burstArea = listPos
    '''
    function _003 : bind object event to specific method
    '''
    def _003_bindAction(self):
        #bind timer event to method of lasting image effect of bursting
        self.timer_lastBurstEffect.Bind(wx.EVT_TIMER, self.SLOT001_lastingBurstEffect)
        #bind destroy action to mainMap object
        self.mainMap.evtCollector.Bind(EVT_DESTROY_GAME_OBJ, self.SLOT002_destroy)
    '''
    function _004 : destroy all object of this class
    '''
    def _004_destroyAllObject(self):
        self.timer_lastBurstEffect.Stop()
        self.timer_lastBurstEffect.Destroy()
        del self
    '''
    function SLOT001 : the slot of lasting effect of bursting
    '''
    def SLOT001_lastingBurstEffect(self, event):
        if self.curBurstImageIndex < LIST_FILENAME_GAMEOBJECT[GAME_OBJ_BURST_FIRE].__len__() :  #change image of fire
            index = 0
            while index < self.list_burstArea.__len__() :
                self.mainMap.ACT003_changeObj(self.list_burstArea[index], GAME_OBJ_BURST_FIRE, self.curBurstImageIndex)
                index = index + 1
            self.curBurstImageIndex = self.curBurstImageIndex + 1
        else :
            #set product
            if LIST_BURST_PRODUCT.has_key(str(self.burstObj)) :  #get product from table - LIST_BURST_PRODUCT
                changeObjType = LIST_BURST_PRODUCT[str(self.burstObj)]
            else :  #no product
                changeObjType = GAME_OBJ_BLACK
            #create bursting product
            index = 0
            while index < self.list_burstArea.__len__() :
                self.mainMap.ACT003_changeObj(self.list_burstArea[index], changeObjType, 0)
                if changeObjType != GAME_OBJ_BLACK :
                    self.mainMap.ACT006_createGameObj(changeObjType, self.list_burstArea[index])
                index = index + 1
            #destroy this object
            self._004_destroyAllObject()
    '''
    function SLOT002 : the slot of destroying 
    '''
    def SLOT002_destroy(self, event):
        if not event.isClearAll :
            if event.delObjType == GAME_OBJ_BURST_FIRE and self.posCenter[0] == event.delPos[0] and \
            self.posCenter[1] == event.delPos[1] :
                self._004_destroyAllObject()
        else :
            self._004_destroyAllObject()
        event.Skip()